let rtcroom = require('../../utils/rtcroom.js');
let app = getApp();
Component({
  properties: {
    roomID: {
      type: String,
      value: '',
    },
    roomInfo: {
      type: String,
      value: '',
    },
    beauty: {
      type: Number,
      value: 5,
    }, // 美颜程度，取值为0~9
    aspect: {
      type: String,
      value: '3:4',
    }, // 设置画面比例，取值为'3:4'或者'9:16'
    minBitrate: {
      type: Number,
      value: 200,
    }, // 设置码率范围为[minBitrate,maxBitrate]，四人建议设置为200~400
    maxBitrate: {
      type: Number,
      value: 400,
    },
    muted: {
      type: Boolean,
      value: false,
    }, // 设置推流是否静音
    debug: {
      type: Boolean,
      value: false,
    }, // 是否显示log
    createRoom: {
      type: Boolean,
      value: false,
    },
  },
  data: {
    pusherContext: '',
    hasPushStarted: false,
    pushURL: '',
    members: [{}, {}],
    maxMembers: 2,
    self: {},
    hasExitRoom: true,

    // 数据统计
    push_stream_start: 0,
    push_stream_tap: 0,
    push_info: '',
    play_stream_start: 0,
    play_stream_end: 0,
    play_stream_tap: 0,
    play_info: '',

    ERROR_GET_PUSH_URL: -1, // 获取推流失败
    ERROR_CREATE_ROOM: -2, // 创建房间失败
    ERROR_ENTER_ROOM: -3, // 进房失败
    ERROR_OPEN_CAMERA: -4, // 打开摄像头失败
    ERROR_OPEN_MIC: -5, // 打开麦克风失败
    ERROR_PUSH_DISCONNECT: -6, // 推流连接断开
    ERROR_CAMERA_MIC_PERMISSION: -7, // 获取不到摄像头或者麦克风权限
    ERROR_REACH_MAX_MEMBERS: -8, // 房间到达最大人数限制
    isPull: true, // 是否满屏
    frontCamera: true, // 摄像头是否翻转
    playerIsPull: false, // player 是否全屏
    isTimeout: false,
  },
  mealInterval: null,
  heartInterval: null,
  accountAuthChecked: false,
  isAccountAuth: false,
  ready() {
    if (!this.data.pusherContext) {
      this.data.pusherContext = wx.createLivePusherContext('rtcpusher');
    }
    self = this;
    this.getBaseInfo();
    this.getSystemInfo();
  },
  detached() {
    console.log('组件 detached');
    clearTimeout(self.data.timerID);
    this.exitRoom(true);
  },
  methods: {
    start() {
      return new Promise((resolve, reject) => {
        self = this;
        self.data.hasExitRoom = false;
        // 设置rtcroom监听事件
        rtcroom.setListener({
          onPusherJoin: self.onPusherJoin,
          onPusherQuit: self.onPusherQuit,
          onRoomClose: self.onRoomClose,
          onRecvRoomTextMsg: self.onRecvRoomTextMsg,
        });

        if (self.data.createRoom) {
          // 创建房间，获取推流URL，开始推流
          self.createRoom().then(res => {
            resolve(res, self.data.pushURL);
          });
        } else {
          // 获取推流URL，开始推流
          self.getPushURLAndStartPush(self.data.roomID);
          resolve(self.data.roomID, self.data.pushURL);
        }
        self.setTimer();

        if (self.data.roomID) {
          // 获取除了自己外房间所有的成员信息
          rtcroom.getPushers({
            data: {
              roomID: self.data.roomID,
            },
            success: function (res) {
              if (res.pushers.length > self.data.maxMembers) {
                self.postErrorEvent(self.data.ERROR_REACH_MAX_MEMBERS, '房间已达到最大人数限制');
                return;
              }
              // 拉流开始时间戳
              if (!self.data.play_stream_start) {
                self.data.play_stream_start = Number(new Date());
                self.data.play_stream_tap = Number(new Date());
              }
              for (let i = 0; i < self.data.maxMembers; i++) {
                if (res.pushers[i]) {
                  let pusher = res.pushers[i];
                  pusher.loading = false;
                  pusher.playerContext = wx.createLivePlayerContext(pusher.userID);
                  self.data.members[i] = pusher;
                }
              }
              self.setData({
                members: self.data.members,
              });
            },
          });
        }
      });
    },
    setTimer() {
      clearTimeout(self.data.timerID);
      const timerID = setTimeout(() => {
        self.setData({
          isTimeout: true,
        }, () => {
          self.exitRoom(true);
        });
      }, 100000);
      self.setData({ timerID });
    },
    stop() {
      self.data.hasExitRoom = true;
      console.log('组件停止');
      self.exitRoom();
    },
    pause() {
      if (!self.data.pusherContext) {
        self.data.pusherContext = wx.createLivePusherContext('rtcpusher');
      }
      self.data.pusherContext && self.data.pusherContext.pause();

      self.data.members.forEach(function (val) {
        val.playerContext && val.playerContext.pause();
      });
    },
    resume() {
      if (!self.data.pusherContext) {
        self.data.pusherContext = wx.createLivePusherContext('rtcpusher');
      }
      self.data.pusherContext && self.data.pusherContext.resume();

      self.data.members.forEach(function (val) {
        val.playerContext && val.playerContext.resume();
      });
    },
    switchCamera() {
      if (!self.data.pusherContext) {
        self.data.pusherContext = wx.createLivePusherContext('rtcpusher');
      }
      self.data.pusherContext && self.data.pusherContext.switchCamera({});
    },
    sendTextMsg(msg) {
      if (!msg) {
        return;
      }
      rtcroom.sendRoomTextMsg({
        data: {
          msg: msg,
        },
      });
    },
    getAccountInfo() {
      let accountInfo = rtcroom.getAccountInfo();
      return {
        userID: accountInfo.userID, // 用户ID
        userName: accountInfo.userName, // 用户昵称
        userAvatar: accountInfo.userAvatar, // 用户头像URL
        userSig: accountInfo.userSig, // IM登录凭证
        sdkAppID: accountInfo.sdkAppID, // IM应用ID
        accountType: accountInfo.accountType, // 账号集成类型
        accountMode: accountInfo.accountMode, // 帐号模式，0-表示独立模式，1-表示托管模式
        token: accountInfo.token, // 登录RoomService后使用的票据
      };
    },
    getRoomInfo() {
      let roomInfo = rtcroom.getRoomInfo();
      return {
        roomID: roomInfo.roomID, // 视频位房间ID
        roomCreator: roomInfo.roomCreator, // 房间创建者
        roomInfo: roomInfo.roomInfo, // 房间自定义信息（如作为房间名称）
        mixedPlayURL: roomInfo.mixedPlayURL, // 混流地址
        pushers: roomInfo.pushers, // 当前用户信息
        isDestory: roomInfo.isDestory, // 是否已解散
      };
    },
    createRoom() {
      let roomInfo = rtcroom.getRoomInfo();
      return new Promise((resolve, reject) => {
        rtcroom.createRoom({
          data: {
            roomInfo: self.data.roomInfo,
            roomID: self.data.roomID,
          },
          success: function (res) {
            console.log('创建房间成功，房间信息：', res);
            console.log('模板消息参数', roomInfo);

            app.util.request({
              url: 'entry/wxapp/index',
              module: 'cm_video_alarm',
              data: {
                op: 'sendMsgToKefu',
                roomID: roomInfo.roomID,
                roomName: roomInfo.roomInfo,
                openid: wx.getStorageSync('openid') || wx.getStorageSync('OPENID'),
              },
              success: res => {
                console.log('模板消息回调', res);
              },
            });
            self.data.roomID = res.roomID;
            self.checkAuth().then(() => {
              if (self.isAccountAuth) {
                return self.createAccountRoom(res.roomID);
              }
            }).then(() => {
            self.getPushURLAndStartPush(self.data.roomID);
              if (self.isAccountAuth) {
                self.mealInterval = setInterval(() => {
                  self.checkMeal();
                }, 10 * 60 * 1000);
                self.heartInterval = setInterval(() => {
                  self.accountHeart();
                }, 60 * 1000);
              }
            resolve(res.roomID);
            }).catch(() => {
              self.stop();
            });

          },
          fail: function (res) {
            console.error('创建房间失败:', res);
            self.exitRoom();
            self.postErrorEvent(self.data.ERROR_CREATE_ROOM, '创建房间失败[' + res.errMsg + '(' + res.errCode + ')]');
          },
        });
      });
    },
    enterRoom() {
      rtcroom.enterRoom({
        data: {
          roomID: self.data.roomID,
          pushURL: self.data.pushURL,
          roomInfo: self.data.roomInfo,
        },
        success: function (res) {
          console.log('进房成功');
          self.checkAuth().then(() => {
            if (self.isAccountAuth) {
              self.joinAccountRoom();
              self.heartInterval = setInterval(() => {
                self.accountHeart();
              }, 60 * 1000);
            }
          });
        },
        fail: function (res) {
          console.error('进房失败:', res);
          self.exitRoom();
          let errText = res.errMsg === 'undefined[-1]'? '咨询已结束':'进入房间失败[' + res.errMsg + '(' + res.errCode + ')]';
          self.postErrorEvent(self.data.ERROR_ENTER_ROOM, errText);
        },
      });
    },
    exitRoom(needCallback) {
      if (!self.data.pusherContext) {
        self.data.pusherContext = wx.createLivePusherContext('rtcpusher');
      }
      self.data.pusherContext && self.data.pusherContext.stop && self.data.pusherContext.stop();

      self.data.members.forEach(function (val) {
        val.playerContext && val.playerContext.stop();
      });

      for (let i = 0; i < self.data.maxMembers; i++) {
        self.data.members[i] = {};
      }
      self.setData({
        members: self.data.members,
      });
      rtcroom.exitRoom({});
      if (self.isAccountAuth) {
        self.leaveAccountRoom();
        if (self.data.createRoom) {
          self.destroyAccountRoom();
        }
        if (self.mealInterval) {
          clearInterval(self.mealInterval);
        }
        if (self.heartInterval) {
          clearInterval(self.heartInterval);
        }
      }

      const memberCount  =  this.getRoomInfo().pushers.length;
      if (needCallback) {
        self.postEvent('roomClosed', 0, {
          isTimeout: self.data.isTimeout,
          memberCount,
        });
      }
    },
    checkAuth() {
      return new Promise((resolve, reject) => {
        if (this.accountAuthChecked) {
          return resolve();
        }
        app.util.request({
          url: 'wxapp/accounting/is_auth',
          module: 'cm_video_alarm',
          success: res => {
            if (res.data.errno == 0) {
              this.accountAuthChecked = true;
              this.isAccountAuth = res.data.data && res.data.data.is_auth == 1;
              return resolve();
            }
          },
        });
      });
    },
    createAccountRoom(roomid) {
      return new Promise((resolve, reject) => {
        app.util.request({
          url: 'wxapp/accounting/createRoom',
          data: {
            roomid,
            type: 2,
          },
          module: 'cm_video_alarm',
          success: res => {
            if (res.data.errno == 0) {
              resolve();
            } else {
              wx.showModal({
                title: '提示',
                content: res.data.message,
                showCancel: false,
              });
              reject(res.data.message);
            }
          },
        });
      });
    },

    destroyAccountRoom() {
      app.util.request({
        url: 'wxapp/accounting/destroyRoom',
        data: {
          roomid: this.data.roomID,
          type: 2,
        },
        module: 'cm_video_alarm',
        success: res => {

        },
      });
    },
    joinAccountRoom() {
      app.util.request({
        url: 'wxapp/accounting/joinRoom',
        data: {
          roomid: this.data.roomID,
          type: 2,
        },
        module: 'cm_video_alarm',
        success: res => {

        },
      });
    },
    leaveAccountRoom() {
      app.util.request({
        url: 'wxapp/accounting/leaveRoom',
        data: {
          op: 'leaveRoom',
          roomid: this.data.roomID,
          type: 2,
        },
        module: 'cm_video_alarm',
        success: res => {

        },
      });
    },
    checkMeal() {
      app.util.request({
        url: 'wxapp/accounting/checkMeal',
        data: {
          meal_type: 'trtc',
        },
        module: 'cm_video_alarm',
        success: res => {
          if (res.data && res.data.errno == 1) {
            wx.showModal({
              title: '提示',
              content: '音视频服务套餐时长不足，请联系管理员充值',
              showCancel: false,
            });
          }
        },
        fail: res => {
          if (res.data && res.data.errno == 2) {
            wx.showModal({
              title: '提示',
              content: '音视频服务套餐时长不足，需要充值后才能继续使用',
              showCancel: false,
              success: () => {
                wx.navigateBack({ delta: 1 });
              },
            });
          }
        },
      });
    },
    accountHeart() {
      app.util.request({
        url: 'wxapp/accounting/heart',
        data: {
          roomid: this.data.roomID,
        },
        module: 'cm_video_alarm',
        success: res => {

        },
      });
    },
    postErrorEvent(errCode, errMsg) {
      self.postEvent('error', errCode, errMsg);
    },
    postEvent(tag, code, detail) {
      self.triggerEvent('onRoomEvent', {
        tag: tag,
        code: code,
        detail: detail,
      }, {});
    },
    getPushURLAndStartPush(roomID) {
      let data = {};
      if (roomID) {
        data.roomID = roomID;
      }
      rtcroom.getPushURL({
        data: data,
        success: function (res) {
          // 开启推流
          if (!self.data.hasExitRoom) {
            self.data.hasPushStarted = false;
            self.setData({
              push_stream_start: Number(new Date()),
              push_stream_tap: Number(new Date()),
              pushURL: res.pushURL,
            });
          }
        },
        fail: function (res) {
          console.error('获取推流地址失败:', JSON.stringify(res));
          self.postErrorEvent(self.data.ERROR_GET_PUSH_URL, '获取推流地址失败[' + res.errMsg + '(' + res.errCode + ')]');
        },
      });
    },
    onPusherJoin(res) {
      // 拉流开始时间戳
      clearTimeout(self.data.timerID);
      if (!self.data.play_stream_start) {
        self.data.play_stream_start = Number(new Date());
        self.data.play_stream_tap = Number(new Date());
      }
      res.pushers.forEach(function (val) {
        let emptyIndex = -1;
        let hasPlay = false;
        for (let i = 0; self.data.members && i < self.data.members.length; i++) {
          if (self.data.members[i].userID && self.data.members[i].userID == val.userID) {
            hasPlay = true;
          } else if (!self.data.members[i].userID && emptyIndex == -1) {
            emptyIndex = i;
          }
        }
        if (!hasPlay && emptyIndex != -1) {
          val.loading = false;
          val.playerContext = wx.createLivePlayerContext(val.userID);
          self.data.members[emptyIndex] = val;
        }
      });
      self.setData({
        members: self.data.members,
      });
    },
    onPusherQuit(res) {
      res.pushers.forEach(function (val) {
        for (let i = 0; i < self.data.maxMembers; i++) {
          if (self.data.members[i].userID == val.userID) {
            self.data.members[i] = {};
          }
        }
      });
      self.setData({
        members: self.data.members,
      });
      clearTimeout(self.data.timerID);
      // 判断客服身份
      app.util.request({
        url: 'entry/wxapp/alarm',
        data: {
          op: 'checkSpecialist',
          user_id: res.pushers[0].userID,
        },
        module: 'cm_video_alarm',
        success:res=>{
          if(res.data.errno) return;
          console.log(res.data.data)
          if(res.data.data == 1){
      wx.showModal({
        title: '提示',
        content: '对方已挂断',
        showCancel: false,
        success() {
          self.exitRoom(true);
        },
      });
          }
        }
      })
    },
    onRoomClose() {
      console.log('房间解散');
      self.exitRoom(true);
    },
    onRecvRoomTextMsg(res) {
      /**
       * res:
       * {
       *   roomID: roomInfo.roomID,
       *   userID: msg.fromAccountNick,
       *   nickName: msg.nickName,
       *   headPic: msg.headPic,
       *   textMsg: msg.content,
       *   time: msg.time
       * }
       */
      self.postEvent('recvTextMsg', 0, JSON.stringify(res));
    },
    // 推流事件
    onPush(e) {
      if (!self.data.pusherContext) {
        self.data.pusherContext = wx.createLivePusherContext('rtcpusher');
      }
      let code;
      if (e.detail) {
        code = e.detail.code;
      } else {
        code = e;
      }
      console.log('推流情况：', code);
      // 推流情况打点记录
      if (self.data.push_stream_tap != -1) {
        self.data.push_stream_tap = Number(new Date()) - self.data.push_stream_tap;
        self.data.push_info += '[' + code + ':' + self.data.push_stream_tap + ']';
        self.data.push_stream_tap = Number(new Date());
      }
      let errmessage = '';
      switch (code) {
        case 1002:
        {
          if (!self.data.hasPushStarted) {
            self.data.hasPushStarted = true;
            // 推流成功，进入房间
            self.enterRoom();
            self.data.push_stream_tap = -1;
          }
          break;
        }
        case -1301:
        {
          console.error('打开摄像头失败: ', code);
          self.postErrorEvent(self.data.ERROR_OPEN_CAMERA, '打开摄像头失败');
          self.exitRoom();
          break;
        }
        case -1302:
        {
          console.error('打开麦克风失败: ', code);
          self.postErrorEvent(self.data.ERROR_OPEN_MIC, '打开麦克风失败');
          self.exitRoom();
          break;
        }
        case -1307:
        {
          console.error('推流连接断开: ', code);
          self.postErrorEvent(self.data.ERROR_PUSH_DISCONNECT, '推流连接断开');
          self.exitRoom();
          break;
        }
        case 5000:
        {
          console.log('收到5000: ', code);
          // 收到5000就退房
          self.exitRoom();
          break;
        }
        default:
        {
          // console.log('推流情况：', code);
        }
      }
    },
    // 标签错误处理
    onError(e) {
      console.log('推流错误：', e);
      e.detail.errCode == 10001 ? (e.detail.errMsg = '未获取到摄像头功能权限，请删除小程序后重新打开') : '';
      e.detail.errCode == 10002 ? (e.detail.errMsg = '未获取到录音功能权限，请删除小程序后重新打开') : '';
      self.postErrorEvent(self.data.ERROR_CAMERA_MIC_PERMISSION, e.detail.errMsg || '未获取到摄像头、录音功能权限，请删除小程序后重新打开');
    },
    // 播放器live-player回调
    onPlay(e) {
      // 拉流情况打点记录
      if (self.data.play_stream_tap != -1) {
        self.data.play_stream_tap = Number(new Date()) - self.data.play_stream_tap;
        self.data.play_info += '[' + e.detail.code + ':' + self.data.play_stream_tap + ']';
        self.data.play_stream_tap = Number(new Date());
      }
      self.data.members.forEach(function (val) {
        if (e.currentTarget.id == val.userID) {
          switch (e.detail.code) {
            case 2007:
            {
              console.log('视频播放loading: ', e);
              val.loading = true;
              break;
            }
            case 2004:
            {
              console.log('视频播放开始: ', e);
              val.loading = false;
              // 拉流成功耗时
              if (!self.data.play_stream_end) {
                self.data.play_stream_end = Number(new Date());
                self.data.play_stream_tap = -1;
                console.warn('int64_tc_play_stream' + self.data.play_stream_start + ', ' + self.data.play_stream_end);
              }
              break;
            }
            default:
            {
              console.log('拉流情况：', e);
            }
          }
        }
      });
      self.setData({
        members: self.data.members,
      });
    },
    switchPull() {
      let {
        isPull,
      } = this.data;
      isPull = !isPull;
      this.setData({
        isPull,
      });
      console.log('==================点击', isPull);
    },
    changeCamera() { // 翻转摄像头
      this.switchCamera();
      this.setData({
        frontCamera: !this.data.frontCamera,
      });
    },
    setBeauty() { // 开启美颜
      let {
        beauty,
      } = this.data;
      beauty = beauty === 0 ? 5 : 0;
      this.setData({
        beauty,
      });
    },
    changeMute() { // 是否关闭声音
      let {
        muted,
      } = this.data;
      muted = !muted;
      this.setData({
        muted,
      });
    },
    closeBack() {
      this.exitRoom(true);
    },
    changePlayer() {
      let { playerIsPull } = this.data;
      this.setData({
        playerIsPull: !playerIsPull,
      });
    },
    getBaseInfo(){
      let { recept_person='' } = wx.getStorageSync('alarmBaseInfo');
      this.setData({
        recept_person,
      });
    },
    getSystemInfo() {
      wx.getSystemInfo({
        success: e => {
          const statusBarHeight = e.statusBarHeight;
          const menuInfo = wx.getMenuButtonBoundingClientRect();
          const menuBarHeight = ( menuInfo.top - statusBarHeight) + menuInfo.height;
          const totalHeight = statusBarHeight + menuBarHeight;
          this.setData({
            totalHeight,
          });
        },
      });
    },
  },
});
